package com.zzyl.nursing.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.thread.UserThreadLocal;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.dto.ReservationDto;
import com.zzyl.nursing.dto.ReservationPageDto;
import com.zzyl.nursing.mapper.MemberReservationMapper;
import com.zzyl.nursing.service.IMemberReservationService;
import com.zzyl.nursing.vo.ReservationVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Service
public class MemberReservationServiceImpl  implements IMemberReservationService {

    // 每个时间段最大预约次数
    private static final int MAX_RESERVATIONS = 6;

    //每人每天最多预约次数
    private static final int MAX_DAILY_RESERVATIONS = 3;

    @Autowired
    MemberReservationMapper memberReservationMapper;

    /**
     * 新增预约
     * @param dto
     */
    @Override
    public void insertReservationInfo(ReservationDto dto) {
        Long userId = UserThreadLocal.getUserId();
        Integer count = getCancelledReservationCount(userId);
//        if (count >= MAX_DAILY_RESERVATIONS) {
//            throw new BaseException("您的取消预约次数已达3次，今日不可继续预约");
//        }

        Reservation reservation = new Reservation();
        BeanUtils.copyProperties(dto,reservation);
        reservation.setStatus(0);
        reservation.setCreateTime(LocalDateTime.now());
        reservation.setUpdateTime(LocalDateTime.now());
        reservation.setCreateBy(userId);
        reservation.setUpdateBy(userId);
        memberReservationMapper.insertReservationInfo(reservation);
    }

    /**
     *
     * @param dto
     * @return
     */
    @Override
    public List<ReservationVo> getReservationList(ReservationPageDto dto) {

        Long userId = UserThreadLocal.getUserId();
        Integer status = dto.getStatus();
        List<ReservationVo> list = memberReservationMapper.selectReservationAll(status, userId);
        System.out.println("list = " + list);
        return list;
    }

    /**
     * 更新预约信息----取消预约
     * @param id
     */
    @Override
    public void updateReservationInfo(Long id) {
        Long  userId = UserThreadLocal.getUserId();
        memberReservationMapper.updateReservationStatus(id,userId);
    }

    /**
     * 查询取消预约的次数
     * @param userId
     * @return
     */
    @Override
    public Integer getCancelledReservationCount(Long userId) {
        // 1.获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 2. 计算当天起始时间：当天00:00:00
        LocalDateTime start = now.with(LocalTime.MIN); // 等同于 now.toLocalDate().atStartOfDay()

        // 3. 计算当天结束时间：次日00:00:00（便于SQL中使用 < 条件）
        LocalDateTime end = now.plusDays(1).with(LocalTime.MIN);
        Integer count = memberReservationMapper.getCancelledReservationCount(userId,start,end);
        return count;
    }


    /**
     * 查询各个时间段的预约次数
     * @param time
     * @return
     */
    @Override
    public List<Map<String, Object>> countByTime(Long time) {
        // 将时间戳转换为日期字符串（yyyy-MM-dd）
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(date);

        // 生成所有时间段（8:00到18:00，每半小时）
        List<String> timeSlots = generateTimeSlots(dateStr);

        // 查询已预约的时间段及数量
        List<Map<String, Object>> reservedList = memberReservationMapper.countReservationsByTimeSlots(timeSlots);

        // 计算剩余预约次数
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> reserved : reservedList) {
            Map<String, Object> item = new HashMap<>();
            item.put("time", reserved.get("time_slot"));

            int reservedCount = Integer.parseInt(reserved.get("count").toString());
            int remaining = Math.max(0, MAX_RESERVATIONS - reservedCount);
            item.put("count", remaining);

            result.add(item);
        }

        return result;
    }

    /**
     * 生成从8:00到18:00的所有半小时时间段
     */
    private List<String> generateTimeSlots(String dateStr) {
        List<String> timeSlots = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            // 起始时间：8:00
            Date startTime = sdf.parse(dateStr + " 08:00:00");
            // 结束时间：18:00
            Date endTime = sdf.parse(dateStr + " 18:00:00");

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);

            while (calendar.getTime().before(endTime) || calendar.getTime().equals(endTime)) {
                timeSlots.add(sdf.format(calendar.getTime()));
                // 增加30分钟
                calendar.add(Calendar.MINUTE, 30);
            }
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
        }

        return timeSlots;
    }


    @Override
    public void updateReservationStatus() {
        //1.查询所有预约记录
//        List<Reservation> list = this.list();
        List<Reservation> list = memberReservationMapper.selectAllReservateionInfo();
        LocalDateTime now = LocalDateTime.now();
        //2.遍历预约记录,判断是否过期
        for (Reservation reservation : list) {
            if(reservation.getStatus() == 0 && reservation.getTime().isBefore(now)){
                //3.更新预约状态为已过期:3
                reservation.setStatus(3);
                memberReservationMapper.updateById(reservation);
            }
        }
    }
}
